﻿using System;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Input;

namespace WickedFlame.GenDock
{
    public abstract class Anchor : ContentControl, IContentContainer
    {
        protected List<FrameworkElement> VisibleChildren;
        internal Dictionary<ButtonBase, ContentDocument> listContents;

        static Anchor()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Anchor), new FrameworkPropertyMetadata(typeof(Anchor)));
        }

        public Anchor()
        {
            VisibleChildren = new List<FrameworkElement>();
            listContents = new Dictionary<ButtonBase, ContentDocument>();

            this.Loaded += new RoutedEventHandler(OnLoaded);
            
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
        }


        Panel _baseStackPanel;
        Panel BaseStackPanel
        {
            get
            {
                if (_baseStackPanel == null)
                    _baseStackPanel = GetTemplateChild("baseStackPanel") as Panel;
                
                return _baseStackPanel;
            }
        }

        internal virtual void InvalidateContent()
        {
            try
            {
                BaseStackPanel.Children.Clear();

                foreach (FrameworkElement element in VisibleChildren)
                {
                    BaseStackPanel.Children.Add(element);
                }
            }
            catch { }
        }

        internal void AddContent(ButtonBase button, ContentDocument content)
        {
            listContents.Add(button, content);
            button.MouseLeftButtonDown += new MouseButtonEventHandler(OnButtonMouseLeftButtonDown);
            button.MouseMove += new MouseEventHandler(OnButtonMouseMove);
        }

        /// <summary>
        /// Overriden to get a reference to underlying template elements
        /// </summary>
        public override void OnApplyTemplate()
        {
            InvalidateContent();

            base.OnApplyTemplate();
        }

        public void ClearContent()
        {
            if (this.BaseStackPanel != null)
                this.BaseStackPanel.Children.Clear();

            this.VisibleChildren.Clear();
        }

        //protected override int VisualChildrenCount
        //{
        //    get
        //    {
        //        if (BaseStackPanel != null)
        //            return BaseStackPanel.Children.Count;

        //        return 0;
        //    }
        //}

        #region IContentContainer Member

        public abstract void AddContent(ContentDocument content);

        public abstract void AddContent(ContentDocument content, Point point);

        public abstract void RemoveContent(ContentDocument content);

        public abstract bool ShowContent(Type type);

        public abstract bool ShowContent(ContentDocument content);

        #endregion

        Point startPoint;

        private void OnButtonMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            startPoint = e.GetPosition(null);
        }

        private void OnButtonMouseMove(object sender, MouseEventArgs e)
        {
            if (startPoint.X == 0.0 && startPoint.Y == 0.0)
                startPoint = e.GetPosition(null);
            // Get the current mouse position
            Point mousePos = e.GetPosition(null);
            Vector diff = startPoint - mousePos;

            if (e.LeftButton == MouseButtonState.Pressed &&
                (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
                Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
            {
                ContentDocument content = listContents[sender as ButtonBase];
                DataObject dragData = new DataObject("content", content);

                RemoveContent(content);
                if (content.Parent is DockableWindow && this is IDockableWindowPresenter)
                {
                    //(content.Parent as DockedWindow).RemoveContent(content);
                    //(content.Parent as DockableWindow).Close();
                    ((IDockableWindowPresenter)this).ReleaseDockedWindow(content.Parent as DockableWindow);
                }
                //(sender as ButtonBase).CaptureMouse();
                //inDragDrop = true;
                DragDropEffects de = DragDrop.DoDragDrop(this, dragData, DragDropEffects.Move);
                //string test = "";
                //(sender as ButtonBase).ReleaseMouseCapture();

            }
        }

        /// <summary>
        /// Compute the desidered size of the panel
        /// </summary>
        /// <param name="availableSize"></param>
        /// <returns></returns>
        protected override Size MeasureOverride(Size availableSize)
        {
            if (Content != null)
            {
                (Content as UIElement).Measure(availableSize);
                //return (Content as UIElement).DesiredSize;
                return new Size((Content as UIElement).DesiredSize.Width + this.Margin.Left + this.Margin.Right,
                    (Content as UIElement).DesiredSize.Height + this.Margin.Top + this.Margin.Bottom);
            }

            return base.MeasureOverride(availableSize);

        }

        //protected override Size ArrangeOverride(Size arrangeBounds)
        //{
        //    return base.ArrangeOverride(arrangeBounds);
        //}
    }
}
